using System;

namespace PDUConverter
{
    /// <summary>
    /// Represents the the first octet of an SMS-SUBMIT-PDU.
    /// </summary>
    public class SmsSubmitMessageFlags : OutgoingMessageFlags
    {
        private bool rejectDuplicates;
        private bool replyPathExists;
        private bool requestStatusReport;
        private const byte TP_MTI_SMS_Submit = 1;
        private const byte TP_RD = 4;
        private const byte TP_RP = 0x80;
        private const byte TP_SRR = 0x20;
        private const byte TP_UDHI = 0x40;
        private const byte TP_VPF_Absolute = 0x18;
        private const byte TP_VPF_Enhanced = 8;
        private const byte TP_VPF_Relative = 0x10;
        private bool userDataHeaderPresent;
        private ValidityPeriodFormat validityPeriodFormat;

        /// <summary>
        /// Initializes a new instance of the <see cref="T:GsmComm.PduConverter.SmsSubmitMessageFlags" /> class.
        /// </summary>
        /// <remarks>
        /// Default settings are:
        /// <list type="bullet">
        /// <item><description>
        /// ReplyPathExists = false
        /// </description></item>
        /// <item><description>
        /// UserDataHeaderPresent = false
        /// </description></item>
        /// <item><description>
        /// RequestStatusReport = false
        /// </description></item>
        /// <item><description>
        /// ValidityPeriodFormat = ValidityPeriodFormat.Unspecified
        /// </description></item>
        /// <item><description>
        /// RejectDuplicates = false
        /// </description></item>
        /// <item><description>
        /// MessageType = OutgoingMessageType.SmsSubmit
        /// </description></item>
        /// </list>
        /// </remarks>
        public SmsSubmitMessageFlags()
        {
            this.rejectDuplicates = false;
            this.validityPeriodFormat = PDUConverter.ValidityPeriodFormat.Unspecified;
            this.requestStatusReport = false;
            this.userDataHeaderPresent = false;
            this.replyPathExists = false;
        }

        /// <summary>
        /// Initializes a new instance of the MessageFlags class with a
        /// predefined data byte.
        /// </summary>
        public SmsSubmitMessageFlags(byte flags)
        {
            this.FromByte(flags);
        }

        /// <summary>
        /// Fills the object with values from the data byte.
        /// </summary>
        protected override void FromByte(byte b)
        {
            OutgoingMessageType smsSubmit = OutgoingMessageType.SmsSubmit;
            if ((b & 1) > 0)
            {
                smsSubmit = OutgoingMessageType.SmsSubmit;
            }
            if (smsSubmit != OutgoingMessageType.SmsSubmit)
            {
                throw new ArgumentException("Not an SMS-SUBMIT message.");
            }
            this.rejectDuplicates = (b & 4) > 0;
            this.validityPeriodFormat = PDUConverter.ValidityPeriodFormat.Unspecified;
            if ((b & 0x18) > 0)
            {
                this.validityPeriodFormat = PDUConverter.ValidityPeriodFormat.Absolute;
            }
            if ((b & 0x10) > 0)
            {
                this.validityPeriodFormat = PDUConverter.ValidityPeriodFormat.Relative;
            }
            if ((b & 8) > 0)
            {
                this.validityPeriodFormat = PDUConverter.ValidityPeriodFormat.Enhanced;
            }
            this.requestStatusReport = (b & 0x20) > 0;
            this.userDataHeaderPresent = (b & 0x40) > 0;
            this.replyPathExists = (b & 0x80) > 0;
        }

        /// <summary>
        /// Returns the byte equivalent of this instance.
        /// </summary>
        /// <returns>The byte value.</returns>
        public override byte ToByte()
        {
            byte num = 0;
            num = (byte) (num | 1);
            if (this.rejectDuplicates)
            {
                num = (byte) (num | 4);
            }
            switch (this.validityPeriodFormat)
            {
                case PDUConverter.ValidityPeriodFormat.Relative:
                    num = (byte) (num | 0x10);
                    break;

                case PDUConverter.ValidityPeriodFormat.Absolute:
                    num = (byte) (num | 0x18);
                    break;

                case PDUConverter.ValidityPeriodFormat.Enhanced:
                    num = (byte) (num | 8);
                    break;
            }
            if (this.requestStatusReport)
            {
                num = (byte) (num | 0x20);
            }
            if (this.userDataHeaderPresent)
            {
                num = (byte) (num | 0x40);
            }
            if (this.replyPathExists)
            {
                num = (byte) (num | 0x80);
            }
            return num;
        }

        /// <summary>
        /// Returns the string equivalent of this instance.
        /// </summary>
        public override string ToString()
        {
            return this.ToByte().ToString();
        }

        /// <summary>
        /// Gets the message type, always returns <see cref="F:GsmComm.PduConverter.OutgoingMessageType.SmsSubmit" />.
        /// </summary>
        public override OutgoingMessageType MessageType
        {
            get
            {
                return OutgoingMessageType.SmsSubmit;
            }
        }

        /// <summary>
        /// Gets or sets if the SC should reject duplicate messages.
        /// </summary>
        public bool RejectDuplicates
        {
            get
            {
                return this.rejectDuplicates;
            }
            set
            {
                this.rejectDuplicates = value;
            }
        }

        /// <summary>
        /// Gets or sets if a reply path exists.
        /// </summary>
        public bool ReplyPathExists
        {
            get
            {
                return this.replyPathExists;
            }
            set
            {
                this.replyPathExists = value;
            }
        }

        /// <summary>
        /// Gets or sets if s status report should be requested.
        /// </summary>
        public bool RequestStatusReport
        {
            get
            {
                return this.requestStatusReport;
            }
            set
            {
                this.requestStatusReport = value;
            }
        }

        /// <summary>
        /// Gets or sets if a user data header is present.
        /// </summary>
        public bool UserDataHeaderPresent
        {
            get
            {
                return this.userDataHeaderPresent;
            }
            set
            {
                this.userDataHeaderPresent = value;
            }
        }

        /// <summary>
        /// Gets or sets the validity period format.
        /// </summary>
        public ValidityPeriodFormat ValidityPeriodFormat
        {
            get
            {
                return this.validityPeriodFormat;
            }
            set
            {
                this.validityPeriodFormat = value;
            }
        }
    }
}